﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Light.Weixin.Model;
using Light.Utility;
using System.Web.Security;
using Light.Framework.Castle;
using LitJson;
using Light.Weixin.Contract;
using System.Net;
using Light.Framework.Model;

namespace Light.Weixin.Model
{
    /// <summary>
    /// WxApp扩展方法
    /// </summary>
    public static class WxAppExtension
    {
        /// <summary>
        /// 获取基础操作的access_token
        /// </summary>
        /// <returns></returns>
        public static string GetBasicToken(this WxApp WxApp)
        {
            return GetBasicToken(WxApp, false);
        }

        /// <summary>
        /// 获取基础操作的access_token
        /// </summary>
        /// <param name="WxApp">当前WxApp</param>
        /// <param name="latest">获取最新token</param>
        /// <returns></returns>
        public static string GetBasicToken(this WxApp WxApp, bool latest)
        {
            Light.Utility.OAuth.OAuthConfig config = new Light.Utility.OAuth.OAuthConfig()
            {
                AppId = WxApp.AppID,
                AppKey = WxApp.AppSecret
            };
            string token = Light.Utility.OAuth.WeixinHelper.GetBasicToken(config, latest);
            //ServerApplication.Logger.LogOperation("获取" + config.AppId + "基础操作的access_token：" + token);
            return token;
        }


        /// <summary>
        /// 获取JsApi权限配置的数组
        /// </summary>
        /// <returns></returns>
        public static string GetJsApiInfo(this WxApp wxApp)
        {
            string timestamp = DateHelper.GetTimeStamp(true);//生成签名的时间戳
            string nonceStr = Guid.NewGuid().ToString("N");//生成签名的随机串
            string url = WebHelper.Request("url");//当前的地址
            string sessionKey = wxApp.AppID + "_jsapi_ticket";

            string jsapi_ticket = "";

            //ticket 缓存7200秒
            if (WebHelper.GetSession(sessionKey) == null)
            {
                try
                {
                    //jsapi_ticket="{\"errcode\":0,\"errmsg\":\"ok\",\"ticket\":\"sM4AOVdWfPE4DxkXGEs8VKXfCB-O_7mZJX5CpwJ4LB4_8mpVWWNAEE1r_bOFqumd25wx_hZcuf-P2tJQSZGuMQ\",\"expires_in\":7200}";
                    jsapi_ticket = WebHelper.HttpGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + wxApp.GetBasicToken(false) + "&type=jsapi", Encoding.UTF8);

                    LitJson.JsonData jd = LitJson.JsonMapper.ToObject(jsapi_ticket);
                    jsapi_ticket = jd["ticket"].ToString();

                    WebHelper.SetSession(sessionKey, jsapi_ticket);
                    WebHelper.CurContext.Session.Timeout = 7200 / 60;
                }
                catch (Exception ex)
                {
                    ServerApplication.Logger.LogError(string.Format("{0} GetJsApiInfo 失败，{1}", wxApp.AppID, ex.Message));
                }
            }
            else
            {
                jsapi_ticket = WebHelper.GetSession(sessionKey);
            }

            string[] ArrayList = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonceStr, "url=" + url };
            Array.Sort(ArrayList);
            string signature = string.Join("&", ArrayList);

            signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
            string result = "{\"appId\":\"" + wxApp.AppID + "\", \"timestamp\":" + timestamp + ",\"nonceStr\":\"" + nonceStr + "\",\"signature\":\"" + signature + "\"}";

            return result;
        }

        /// <summary>
        /// 获取网页授权的access_token 和 openid
        /// </summary>
        /// <param name="wxApp"></param>
        public static void GetAccessTokenAndOpenID(this WxApp wxApp, string code)
        {
            if (wxApp == null)
                return;

            Light.Utility.OAuth.OAuthConfig config = new Light.Utility.OAuth.OAuthConfig()
            {
                AppId = wxApp.AppID,
                AppKey = wxApp.AppSecret
            };

            try
            {
                Dictionary<string, object> dicToken = Light.Utility.OAuth.WeixinHelper.GetAccessToken(config, code);
                if (dicToken != null)
                {
                    wxApp.OpenID = dicToken["openid"].ToString();
                    wxApp.AccessToken = dicToken["access_token"].ToString();
                }
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError(
                    string.Format("公众号：{0} 获取授权token失败，错误详情：{1}", wxApp.OriginalID, ex.Message));
            }

        }

        /// <summary>
        /// 拉取用户信息（需scope为 snsapi_userinfo）
        /// 执行此方法前，请确保wxApp.OpenID和wxApp.AccessToken有值，
        /// 执行 GetAccessTokenAndOpenID 可获取OpenID、AccesToken
        /// </summary>
        /// <param name="wxApp"></param>
        /// <returns></returns>
        public static WxUserInfo GetUserInfo(this WxApp wxApp)
        {

            if (wxApp == null)
                return null;
            else if (String.IsNullOrEmpty(wxApp.AccessToken) || String.IsNullOrEmpty(wxApp.OpenID))
            {
                ServerApplication.Logger.LogError(
                    string.Format("公众号：{0} 授权信息access_token、openid为null 无法获取用户信息", wxApp.OriginalID));

                return null;
            }

            try
            {
                //1.优先从数据库获取
                IWxUserInfoComponent comp = ServerApplication.ComponentFactory.Create<IWxUserInfoComponent>();
                WxUserInfo info = comp.Get(wxApp.OpenID);

                //2.未获取到或信息不是最新的则重新获取
                if (info == null || info.TimeUpdated.Date < DateTime.Now.Date || !info.IsSubscribe)
                {
                    JsonData jsonInfo = Light.Utility.OAuth.WeixinHelper.GetUserInfo(wxApp.AccessToken, wxApp.OpenID);
                    if (info == null)
                    {
                        info = new WxUserInfo();
                        info.WxApp = wxApp;
                    }

                    info.IsSubscribe = true;
                    info = SaveUserInfo(info, jsonInfo);
                }
                return info;
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError(
                    string.Format("公众号：{0} GetUserInfo失败，错误详情：{1}", wxApp.OriginalID, ex.Message));
                return null;
            }
        }

        /// <summary>
        /// 拉取用户信息（需scope为 snsapi_userinfo）
        /// </summary>
        /// <param name="wxApp"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static WxUserInfo GetUserInfo(this WxApp wxApp, string code)
        {
            GetAccessTokenAndOpenID(wxApp, code);
            return GetUserInfo(wxApp);
        }

        /// <summary>
        /// 获取用户基本信息（包括UnionID机制）
        /// 在微信开放平台（open.weixin.qq.com）绑定公众号后，才可获取unionid
        /// </summary>
        /// <param name="wxApp"></param>
        /// <param name="openid"></param>
        /// <returns></returns>
        public static WxUserInfo GetAndSaveUser(this WxApp wxApp, string openid)
        {
            try
            {
                //1.优先从数据库获取
                IWxUserInfoComponent comp = ServerApplication.ComponentFactory.Create<IWxUserInfoComponent>();
                WxUserInfo info = comp.Get(openid);

                //2.未获取到或信息不是最新的则重新获取
                if (info == null || info.TimeUpdated.Date < DateTime.Now.Date || !info.IsSubscribe)
                {
                    JsonData jsonInfo = null;

                    if (wxApp.Type == WxAppType.Website)
                    {
                        string url = string.Format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}",
                            wxApp.AccessToken, openid);
                        jsonInfo = WebHelper.HttpGet(url, Encoding.UTF8);
                    }
                    else
                    {
                        Light.Utility.OAuth.OAuthConfig config = new Light.Utility.OAuth.OAuthConfig
                        {
                            AppId = wxApp.AppID,
                            AppKey = wxApp.AppSecret
                        };
                        jsonInfo = Light.Utility.OAuth.WeixinHelper.GetUser(config, openid);
                    }
                    if (info == null)
                    {
                        info = new WxUserInfo();
                        info.WxApp = wxApp;
                        info.OpenID = openid;
                    }
                    info = SaveUserInfo(info, jsonInfo);
                }
                return info;
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError(
                    string.Format("公众号：{0} GetUser失败，错误详情：{1} {2}", wxApp, ex.Message, ex.StackTrace));

                return new WxUserInfo() { OpenID = openid, WxApp = wxApp };
            }
        }

        /// <summary>
        /// 保存用户信息
        /// </summary>
        /// <param name="info"></param>
        /// <param name="jsonInfo"></param>
        /// <returns></returns>
        private static WxUserInfo SaveUserInfo(WxUserInfo info, JsonData jsonInfo)
        {
            using (new GuestUser())
            {
                if (info == null)
                    throw new Exception("微信用户信息未初始化");
                if (jsonInfo == null)
                    throw new Exception("jsonUserInfo is null");

                info.OpenID = jsonInfo["openid"].ToString();
                try
                {
                    info.IsSubscribe = jsonInfo["subscribe"].ToString() == "1";
                }
                catch { }

                try
                {
                    info.UnionID = jsonInfo["unionid"].ToString();
                }
                catch
                {
                    ServerApplication.Logger.LogError("公众号未添加至微信开放平台，无法获取用户 unionid");
                }
                if (info.IsSubscribe)
                {
                    info.Nickname = jsonInfo["nickname"].ToString();
                    info.HeadImgUrl = jsonInfo["headimgurl"].ToString();
                    info.Country = jsonInfo["country"].ToString();
                    info.Province = jsonInfo["province"].ToString();
                    info.City = jsonInfo["city"].ToString();
                    info.IsMale = jsonInfo["sex"].ToString() == "1";
                }

                OperateResult result = ServerApplication.ComponentFactory.Create<IWxUserInfoComponent>().Save(info);

                //不知道为什么保存后info.ID=0
                //ServerApplication.Logger.LogOperation("保存WxUserInfo 返回，" + JsonConverter.Serialize(result) + " id：" + info.ID);


                return info;
            }
        }

        /// <summary>
        /// 获取公众号下的所有消息模板
        /// </summary>
        /// <param name="wxApp"></param>
        /// <returns></returns>
        public static IList<WxMsgTpl> GetMsgTpls(this WxApp wxApp)
        {
            IWxMsgTplComponent comp = ServerApplication.ComponentFactory.Create<IWxMsgTplComponent>();
            return comp.GetMsgTpls(wxApp.OriginalID);
        }

        /// <summary>
        /// 获取指定名称的消息模板
        /// </summary>
        /// <param name="wxApp"></param>
        /// <param name="tplName"></param>
        /// <returns></returns>
        public static WxMsgTpl GetMsgTpl(this WxApp wxApp, string tplName)
        {
            IWxMsgTplComponent comp = ServerApplication.ComponentFactory.Create<IWxMsgTplComponent>();
            return comp.GetMsgTpl(wxApp, tplName);
        }

        /// <summary>
        /// 发送模板消息
        /// </summary>
        /// <param name="app">微信应用</param>
        /// <param name="msg">消息</param>
        /// <param name="tpl">模板</param>
        public static OperateResult SendTplMsg(this WxApp app, WxTplMsg msg, WxMsgTpl tpl)
        {
            OperateResult result = new OperateResult();
            StringBuilder builder = new StringBuilder();

            builder.Append("{");
            builder.Append("\"touser\":\"" + msg.ToUserOpenID + "\",");
            builder.Append("\"template_id\":\"" + tpl.Number + "\",");
            builder.Append("\"url\":\"" + msg.DetailUrl + "\",");
            builder.Append("\"data\":");
            builder.Append("{");
            builder.Append("\"first\":");
            builder.Append("{");
            builder.Append("\"value\":\"" + msg.FirstWords + "\",");
            builder.Append("\"color\":\"" + tpl.ColorFirstWords + "\"");
            builder.Append("},");

            foreach (var kName in msg.Body.Keys)
            {
                builder.Append("\"" + kName + "\":");
                builder.Append("{");
                builder.Append("\"value\":\"" + msg.Body[kName] + "\",");
                builder.Append("\"color\":\"" + tpl.ColorBody + "\"");
                builder.Append("},");
            }

            builder.Append("\"remark\":");
            builder.Append("{");
            builder.Append("\"value\":\"" + msg.Remark + "\",");
            builder.Append("\"color\":\"" + tpl.ColorRemark + "\"");
            builder.Append("}");
            builder.Append("}");
            builder.Append("}");

            try
            {
                msg.Token = app.GetBasicToken(false);
                string data = WebHelper.HttpPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + msg.Token, builder.ToString().Replace("\r", " ").Replace("\n", " "), Encoding.UTF8);
                LitJson.JsonData jo = LitJson.JsonMapper.ToObject(data);

                string errMsg = jo["errmsg"].ToString();
                string errCode = jo["errcode"].ToString();

                result.IsSucced = errCode == "0";
                result.Message = "[" + errCode + "] " + errMsg;
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError(string.Format("发送模板消息 {0} 失败，{1}", tpl.Number, ex.Message));
                result.IsSucced = false;
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 发送模板消息
        /// </summary>
        /// <typeparam name="T">消息内容相关实体类</typeparam>
        /// <param name="app">公众号</param>
        /// <param name="msg">消息内容（必输值 ToUserOpenID，FirstWords，Remark，DetailUrl）</param>
        /// <param name="tpl">消息模板</param>
        /// <param name="objContent">信息相关对象</param>
        /// <returns></returns>
        public static OperateResult SendTplMsg<T>(this WxApp app, WxTplMsg msg, WxMsgTpl tpl, T objContent)
        {
            OperateResult result = new OperateResult();
            try
            {
                msg.TemplateID = tpl.Number;
                msg.Body.Clear();

                foreach (var key in tpl.Body.Keys)
                {
                    object value = ReflectionHelper.GetPropertyValue<T>(objContent, tpl.Body[key]);
                    if (value != null)
                        msg.Body.Add(key, value.ToString());
                    else
                        msg.Body.Add(key, tpl.Body[key]); //如果不包含属性，则直接替换成原字符
                }
                result = app.SendTplMsg(msg, tpl);
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError(string.Format("发送模板消息 {0} 失败，{1} {2}"
                    , tpl.Number, ex.Message, ex.StackTrace));
                result.IsSucced = false;
                result.Message = ex.Message;
            }
            return result;
        }


        /// <summary>
        /// 向管理员发送消息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="app"></param>
        /// <param name="msg"></param>
        /// <param name="tpl"></param>
        /// <param name="objContent"></param>
        public static OperateResult SendTplMsgToAdmins<T>(this WxApp app, WxTplMsg msg, WxMsgTpl tpl, T objContent)
        {

            OperateResult result = new OperateResult();

            if (String.IsNullOrEmpty(app.AdminOpenIDs))
                ServerApplication.Logger.LogError("请先设置公众号管理员OpendIDs");

            try
            {
                string[] openids = app.AdminOpenIDs.Split(',');
                foreach (var openid in openids)
                {
                    msg.ToUserOpenID = openid;
                    result = app.SendTplMsg<T>(msg, tpl, objContent);
                    if (!result.IsSucced)
                    {
                        ServerApplication.Logger.LogError("向管理员发送微信消息失败，" + result.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                result.IsSucced = false;
                result.Message = ex.Message;
                ServerApplication.Logger.LogError("向管理员发送微信消息失败，" + ex.Message);
            }

            return result;
        }

        /// <summary>
        /// 发送客服消息
        /// </summary>
        /// <param name="app"></param>
        /// <param name="msg">消息</param>
        /// <returns></returns>
        public static OperateResult SendCusMsg(this WxApp app, WxMsg msg)
        {
            OperateResult result = new OperateResult();

            StringBuilder builder = new StringBuilder();
            builder.Append("{");
            builder.Append("\"touser\":\"" + msg.ToUserName + "\",");
            builder.Append("\"msgtype\":\"" + msg.MsgType.ToString().ToLower() + "\",");
            if (msg.MsgType == WxMsgType.Text)
            {
                builder.Append("\"text\":");
                builder.Append("{");
                builder.Append("\"content\":\"" + msg.Content + "\"");

                builder.Append("}");
            }
            else if (msg.MsgType == WxMsgType.Image)
            {
                builder.Append("\"image\":");
                builder.Append("{");
                builder.Append("\"media_id\":\"" + msg.Content + "\"");
                builder.Append("}");
            }
            else if (msg.MsgType == WxMsgType.Voice)
            {
                builder.Append("\"voice\":");
                builder.Append("{");
                builder.Append("\"media_id\":\"" + msg.Content + "\"");
                builder.Append("}");
            }
            else if (msg.MsgType == WxMsgType.ShortVideo)
            {
                builder.Append("\"video\":");
                builder.Append("{");
                builder.Append("\"media_id\":\"" + msg.Content + "\"");
                builder.Append("\"thumb_media_id\":\"" + msg.Content + "\"");
                builder.Append("}");
            }
            else if (msg.MsgType == WxMsgType.Video)
            {
                builder.Append("\"video\":");
                builder.Append("{");
                builder.Append("\"media_id\":\"" + msg.Content + "\"");
                builder.Append("\"thumb_media_id\":\"" + msg.Content + "\"");
                builder.Append("\"title\":\"无\"");
                builder.Append("\"description\":\"无\"");
                builder.Append("}");
            }
            else
            {
                builder.Append("\"text\":");
                builder.Append("{");
                builder.Append("\"content\":\"" + msg.Content + "\"");
                builder.Append("}");
            }
            builder.Append("}");
            try
            {
                string token = app.GetBasicToken(true);
                string url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + token;
                string data = WebHelper.HttpPost(url, builder.ToString(), Encoding.UTF8);
                //ServerApplication.Logger.LogOperation("发送客服消息返回，" + data);

                //{"errcode":0,"errmsg":"ok"}
                LitJson.JsonData json = LitJson.JsonMapper.ToObject(data);
                string errmsg = json["errmsg"].ToString();

                if (errmsg == "ok")
                {
                    result.IsSucced = true;
                    result.Message = "发送成功";
                }
                else
                {
                    result.IsSucced = false;
                    result.Message = errmsg;

                    Light.Utility.OAuth.OAuthConfig config = new Light.Utility.OAuth.OAuthConfig()
                    {
                        AppId = app.AppID,
                        AppKey = app.AppSecret
                    };
                    Light.Utility.OAuth.WeixinHelper.RefreshBasicToken(config);

                }
            }
            catch (Exception ex)
            {
                ServerApplication.Logger.LogError("发送客服消息失败，" + ex.Message);
                result.IsSucced = false;
                result.Message = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 好友关注后，发送客服消息通知邀请者
        /// </summary>
        /// <param name="app"></param>
        /// <param name="newSubscriber">新关注者</param>
        public static void NofityInviter(this WxApp app, WxUserInfo newSubscriber)
        {
            if (newSubscriber != null && newSubscriber.Inviter != null)
            {
                newSubscriber.Inviter.Update();

                //发送消息告知邀请者
                WxMsg msgInviter = new WxMsg();
                msgInviter.Content = string.Format("成功邀请好友 {0} 关注 {1}", newSubscriber.Nickname, app.Name);

                msgInviter.ToUserName = newSubscriber.Inviter.OpenID;
                app.SendCusMsg(msgInviter);
            }
        }

        /// <summary>
        /// 获取默认（unknow）回复消息
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static string GetAnswerDefault(this WxApp app)
        {
            IWxAnswerComponent comp = ServerApplication.ComponentFactory.Create<IWxAnswerComponent>();
            return comp.GetAnswerDefault(app.OriginalID);
        }

        /// <summary>
        /// 创建带参数的二维码ticket
        /// </summary>
        /// <param name="app"></param>
        /// <param name="qrCodeType"></param>
        /// <param name="scenceId">qrCodeType为Temp或Limit时，必须是整型，为LimitStr时，为字符串</param>
        /// <returns></returns>
        public static JsonData GetTicket4QrCode(this WxApp app, QrCodeType qrCodeType, object scenceId)
        {
            if (!StringHelper.IsNumeric(scenceId) && qrCodeType != QrCodeType.LimitStr)
            {
                throw new Exception("qrCodeType为Temp或Limit时，scenceId 必须是整型");
            }

            string data = "";
            if (qrCodeType == QrCodeType.Temp)
            {
                data = "{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\":" + scenceId + " }}}";
            }
            else if (qrCodeType == QrCodeType.Limit)
            {
                data = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": " + scenceId + "}}}";
            }
            else if (qrCodeType == QrCodeType.LimitStr)
            {
                data = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": \"" + scenceId + "\"}}}";
            }

            string url = string.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", app.GetBasicToken(false));
            string jsonStr = WebHelper.HttpPost(url, data, Encoding.UTF8);

            //ServerApplication.Logger.LogOperation("获取到qr_ticket：" + jsonStr);

            //{"ticket":"1111","expire_seconds":60,"url":"http://"}
            return LitJson.JsonMapper.ToObject(jsonStr);
        }

        /// <summary>
        /// 获取二维码
        /// </summary>
        /// <param name="ticket">由GetTicket4QrCode获得</param>
        /// <returns></returns>
        public static System.Drawing.Image GetQrCode(string ticket)
        {
            string url = string.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", WebHelper.CurContext.Server.UrlEncode(ticket));
            return WebHelper.HttpGet(url);
        }

        /// <summary>
        /// 获取带整型参数二维码图片
        /// </summary>
        /// <param name="app"></param>
        /// <param name="qrCodeType"></param>
        /// <param name="scenceId"></param>
        /// <returns></returns>
        public static System.Drawing.Image GetQRCode(this WxApp app, QrCodeType qrCodeType, int scenceId)
        {
            JsonData json = app.GetTicket4QrCode(qrCodeType, scenceId);
            string ticket = json["ticket"].ToString();
            return GetQrCode(ticket);
        }

        /// <summary>
        /// 获取带字符型参数二维码图片
        /// </summary>
        /// <param name="app"></param>
        /// <param name="scenceId"></param>
        /// <returns></returns>
        public static System.Drawing.Image GetQRCode(this WxApp app, string scenceId)
        {
            JsonData json = app.GetTicket4QrCode(QrCodeType.LimitStr, scenceId);
            string ticket = json["ticket"].ToString();
            return GetQrCode(ticket);
        }


        /// <summary>
        /// 上传多媒体文件
        /// </summary>
        /// <param name="app"></param>
        /// <param name="type"></param>
        /// <param name="filepath"></param>
        /// <returns>MediaId</returns>
        public static string UploadMedia(this WxApp app, MediaType type, string filepath)
        {
            try
            {
                System.Net.WebClient wx_upload = new WebClient();

                byte[] result = wx_upload.UploadFile(new Uri(String.Format("https://api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}", app.GetBasicToken(false), type.ToString().ToLower())), filepath);
                string jsonStr = Encoding.Default.GetString(result);//在这里获取json数据，以获取media_id
                //ServerApplication.Logger.LogOperation("上传多媒体文件，微信返回：" + jsonStr);

                LitJson.JsonData json = LitJson.JsonMapper.ToObject(jsonStr);

                return json["media_id"].ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("上传多媒体文件至微信出错，" + ex.Message + " " + ex.StackTrace);
            }

        }

        /// <summary>
        /// 长链接变短链接
        /// </summary>
        /// <param name="app"></param>
        /// <param name="longUrl">http://开头的链接</param>
        /// <returns></returns>
        public static string GetShortUrl(this WxApp app, string longUrl)
        {
            try
            {
                string token = app.GetBasicToken(false);
                string url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=" + token;
                string data = "{\"action\": \"long2short\", \"access_token\": \"" + token + "\" , \"long_url\": \"" + longUrl + "\"}";

                string jsonStr = WebHelper.HttpPost(url, data, Encoding.UTF8);

                LitJson.JsonData json = LitJson.JsonMapper.ToObject(jsonStr);

                if (json["errmsg"].ToString() == "ok")
                {
                    return json["short_url"].ToString();
                }
                else
                {
                    return json["errmsg"].ToString();
                }
            }
            catch (Exception ex)
            {
                throw new Exception("long2short occured error：" + ex.Message + " " + ex.StackTrace);
            }
        }
    }
}
